<template>
  <div :class="{'f-list-wrapper': true, 'f-list-wrapper-bordered': bordered}">
    <div class="f-search-wrapper" v-show="searchEnable">
      <el-input :placeholder="searchPlaceholder" v-model="searchText"
                :suffix-icon="Search"/>
    </div>
    <div class="f-list">
      <div v-for="(item, index) in searchedList" :key="item[keyName]"
           @click="() => selectItem(item)" @dblclick="() => dblclick(item)">
        <div :style="getItemStyle(index)"
             :class="{'f-list-item': true, 'selected-item': item[keyName] === selectedKey}">
            <el-text :class="{'selected-item': item[keyName] === selectedKey}"
                     class="f-list-item-text-wrapper"
                     truncated>
              <slot :item="item">
                <div class="f-list-item-text-wrapper">
                  {{ getItemTitle(item) }}
                </div>
              </slot>
            </el-text>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {Search} from '@element-plus/icons-vue';
import {mergeObject} from '@/utils/CommonUtils';
import {markRaw} from 'vue';

export default {
  name: "FList",
  components: {},
  props: {
    itemStyle: {
      type: Object,
      default: () => {}
    },
    bordered: {
      type: Boolean,
      default: false
    },
    searchEnable: {
      type: Boolean,
      default: true
    },
    color: {
      type: String,
      default: ''
    },
    size: {
      type: String,
      default: 'middle' // small, middle, large
    },
    searchPlaceholder: {
      type: String,
      default: '搜索'
    },
    keyName: {
      type: String,
      default: 'id'
    },
    titleName: {
      type: String,
      default: 'title'
    },
    selectedKey: {
      type: String,
      default: undefined
    },
    dataSource: {
      type: Array,
      default() {
        return [];
      }
    }
  },
  data() {
    return {
      Search: markRaw(Search),
      searchText: undefined,
    };
  },
  methods: {
    getItemTitle(item) {
      return item[this.titleName];
    },
    getItemStyle(index) {
      let res = {marginTop: index === 0 ? '0' : '-1px'};
      if (this.size === 'small') {
        res.height = '20px'
      }
      if (this.color) {
        res.color = this.color
      }
      if (this.itemStyle) {
        mergeObject(this.itemStyle, res);
      }
      return res;
    },
    dblclick(item) {
      let key = this.keyName;
      this.$emit('doubleClick', item);
    },
    selectItem(item) {
      let key = this.keyName;
      if (this.selectedKey === item[key]) return;
      // this.selectedKey = item[key];

      this.$emit('select', item);
    },
    doSearch(list, searchText, titleName) {
      let res = [];
      if (!list) return res;
      for (let i = 0; i < list.length; i++) {
        let value = list[i][titleName];
        if (this.match(value, searchText)) {
          res.push(list[i]);
        }
      }
      return res;
    },
    match(value, searchText) {
      if (!searchText || searchText === '') return true;
      if (!value || value === '') return false;

      if (value.indexOf(searchText) !== -1) return true;
      return false;
    }
  },
  computed: {
    searchedList() {
      let list = [...this.dataSource];
      let searchText = this.searchText;
      let titleName = this.titleName;
      return this.doSearch(list, searchText, titleName);
    },
  }
};
</script>

<style>
.f-list-wrapper {
  position: relative;
  overflow: auto;
  height: calc(100% - 2px);
  border: 1px solid rgba(0, 0, 0, 0);
}

.f-list-wrapper-bordered {
  border-color: rgb(220, 223, 230);
}

.f-list-item {
  height: 35px;
  padding-left: 10px;
  display: flex;
  align-items: center;
  cursor: pointer;
  color: rgb(24, 144, 255);
  box-sizing: border-box;
  border: 1px solid rgba(0, 0, 0, 0);
  border-radius: 2px;
  user-select: none;
  width: 100%;
}

.f-list-item:hover {
  border-color: #409EFF;
}

.f-search-wrapper {
  position: sticky;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px 15px;
  background: #ecf5ff;
}

.f-list {

}

.selected-item {
  background: rgb(24, 144, 255);
  color: white !important;
}

.f-list-item .f-list-item-text-wrapper {
  padding-left: 5px;
}
.f-list-item .el-text,
.f-list-item .menu-list-item,
.f-list-item .f-list-item-text-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
}


</style>
